package com.gauss.common.utils;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import com.google.common.collect.MigrateMap;
import com.gauss.exception.GaussException;

public class LikeUtil {

    public static String[]              regexSpecialChars = { "<", ">", "^", "$", "\\", "/", ";", "(", ")", "?", ".",
            "*", "[", "]", "+", "|"                      };
    public static String                escapse           = "\\";

    private static Map<String, Pattern> patterns          = MigrateMap.makeComputingMap(new MapMaker(),
                                                              new Function<String, Pattern>() {

                                                                  public Pattern apply(String pattern) {
                                                                      try {
                                                                          return Pattern.compile(buildPattern(pattern,
                                                                              escapse),
                                                                              Pattern.CASE_INSENSITIVE);
                                                                      } catch (Throwable e) {
                                                                          throw new GaussException(e);
                                                                      }
                                                                  }
                                                              });

    public static boolean isMatch(String pattern, String value) {
        if (StringUtils.equalsIgnoreCase(pattern, value)) {
            return true;
        } else if (StringUtils.isEmpty(value)) {
            return false;
        } else if (StringUtils.isEmpty(pattern)) {
            return false;
        }

        Pattern pat = patterns.get(pattern);
        Matcher m = pat.matcher(value);
        return m.matches();
    }

    private static String buildPattern(String pattern, String escape) {
        char esc = escape.charAt(0);
        pattern = StringUtils.trim(pattern);
        StringBuilder builder = new StringBuilder("^");
        int index = 0, last = 0;
        while (true) {
            // 查找esc
            index = pattern.indexOf(esc, last);
            if (index == -1 || index >= pattern.length()) {
                if (last < pattern.length()) {
                    builder.append(convertWildcard(ripRegex(pattern.substring(last))));
                }
                break;
            }
            if (index > 0) {
                String toRipRegex = StringUtils.substring(pattern, last, index);
                builder.append(convertWildcard(ripRegex(toRipRegex)));
                last = index;
            }
            if (index + 1 < pattern.length()) {
                builder.append(ripRegex(pattern.charAt(index + 1)));
                last = index + 2;
            } else {
                builder.append(pattern.charAt(index));
                last = index + 1;
            }
            if (last >= pattern.length()) {
                break;
            }
        }
        builder.append('$');
        return builder.toString();
    }

    private static String ripRegex(char toRip) {
        char[] chars = new char[1];
        chars[0] = toRip;
        return ripRegex(new String(chars));
    }

    private static String ripRegex(String toRip) {
        for (String c : regexSpecialChars) {
            toRip = StringUtils.replace(toRip, c, "\\" + c);
        }

        return toRip;
    }

    private static String convertWildcard(String toConvert) {
        toConvert = StringUtils.replace(toConvert, "_", "(.)");
        toConvert = StringUtils.replace(toConvert, "%", "(.*)");
        return toConvert;
    }
}
